﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NeuroProzessorSvc
{
    /// <summary>
    /// Stellt die komplette Konfiguration für das Netz und dei umgebung bereit
    /// </summary>
    [Serializable]
    class _cls_Config : MarshalByRefObject, IVisual.I_config
    {
        public static _cls_Config _cfg;

        public int[] _size{get; set;}
        public int Input_Count{get; set;}
        public float alpha{get; set;}
        public float learningRate{get; set;}
        public float momentum{get; set;}
        public float learningLimit{get; set;}
        public bool S2 { get; set; }
        public float learningRate2 { get; set; }
        public float momentum2 { get; set; }
        public float learningLimit2 { get; set; }
        public float[][] _I{get; set;}
        public float[][] _O{get; set;}
        public bool zyklenabbruch{get; set;}
        public IVisual.I_AF.Aktivierungsfunktion AF { get; set;}
        public string mode { get; set; }
        public bool RESTART { get; set; }
        
        public string Visual_IP { get; set; }
        public int Visual_Port { get; set; }

        public bool MAIL_Enabled { get; set; }
        public string MAIL_FROM { get; set; }
        public string MAIL_TO { get; set; }
        public int MAIL_Port { get; set; }
        public string MAIL_Host { get; set; }
        public string MAIL_Betreff { get; set; }
        public bool MAIL_Auth { get; set; }
        public string MAIL_USN { get; set; }
        public string MAIL_PW { get; set; }

        public IVisual.I_Object_Cache Object_Cache { get; set; }

        /// <summary>
        /// Kopierkonstruktor
        /// </summary>
        /// <param name="o"></param>
        public _cls_Config(_cls_Config o)
        {
            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "start");

            this._size = o._size;
            this.Input_Count = o.Input_Count;
            this.alpha = o.alpha;
            this.learningRate = o.learningRate;
            this.momentum = o.momentum;
            this.learningLimit = o.learningLimit;
            this.S2 = o.S2;
            this.learningRate2 = o.learningRate2;
            this.momentum2 = o.momentum2;
            this.learningLimit2 = o.learningLimit2;
            this._I = o._I;
            this._O = o._O;
            this.zyklenabbruch = o.zyklenabbruch;
            this.RESTART = o.RESTART;
            this.AF = o.AF;
            this.mode = o.mode;
            this.Visual_IP = o.Visual_IP;
            this.Visual_Port = o.Visual_Port;
            this.MAIL_Auth = o.MAIL_Auth;
            this.MAIL_Betreff = o.MAIL_Betreff;
            this.MAIL_Enabled = o.MAIL_Enabled;
            this.MAIL_FROM = o.MAIL_FROM;
            this.MAIL_Host = o.MAIL_Host;
            this.MAIL_Port = o.MAIL_Port;
            this.MAIL_PW = o.MAIL_PW;
            this.MAIL_TO = o.MAIL_TO;
            this.MAIL_USN = o.MAIL_USN;
            
            this.Object_Cache = new _cls_Object_Cache();
            this.Object_Cache.EinG_M = o.Object_Cache.EinG_M;
            this.Object_Cache.OCR_Receptors = o.Object_Cache.OCR_Receptors;
            this.Object_Cache.Ap_data = o.Object_Cache.Ap_data;
            this.Object_Cache.TS_windowSize = o.Object_Cache.TS_windowSize;
            this.Object_Cache.TS_predictionSize = o.Object_Cache.TS_predictionSize;
            this.Object_Cache.TS_data = o.Object_Cache.TS_data;
            this.Object_Cache.OCR_regularFonts = o.Object_Cache.OCR_regularFonts;
            this.Object_Cache.OCR_receptorsCount = o.Object_Cache.OCR_receptorsCount;
            this.Object_Cache.OCR_italicFonts = o.Object_Cache.OCR_italicFonts;
            this.Object_Cache.OCR_initialReceptorsCount = o.Object_Cache.OCR_initialReceptorsCount;
            this.Object_Cache.DD_DATA = o.Object_Cache.DD_DATA;
            this.Object_Cache.DD_COLS = o.Object_Cache.DD_COLS;

            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "ende");
        }

        /// <summary>
        /// Default-Config
        /// </summary>
        public _cls_Config()
        {
            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "start");

            Object_Cache = new _cls_Object_Cache();
            _size = new int[2];
            _size[0] = 2;
            _size[1] = 1;

            Input_Count = 2;
            alpha = 2;
            learningRate = 0.1f;
            momentum = 0f;
            learningLimit = 0.1f;
            _I = new float[][] { new float[] { 0, 0 }, new float[] { 0, 1 }, new float[] { 1, 0 }, new float[] { 1, 1 } };
            _O = new float[][] { new float[] { 0 }, new float[] { 1 }, new float[] { 1 }, new float[] { 0 }};
            zyklenabbruch = true;
            RESTART = false;
            AF = IVisual.I_AF.Aktivierungsfunktion.SIGMOID;

            Visual_IP = "";
            Visual_Port = 0;

            MAIL_Enabled = false;
            MAIL_Auth = false;
            MAIL_Port = 25;

            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "ende");
        }

        /// <summary>
        /// Kopiert diese Instanz auf die globale (und loggt)
        /// </summary>
        public bool SET_CFG()
        {
            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "start");

            _cls_Controller _ctrl = new _cls_Controller();
            if (_ctrl.GET_STATE() != System.Threading.ThreadState.Stopped)
                return false;

            _cls_Config._cfg = this;

            if (IVisual._SC.cls_LOG.LOG_LEVEL >= IVisual._SC.cls_LOG.LOGLEVEL.DEBUG)
            {
                string inh = "_size.Length = " + _size.Length;
                for (int i = 0; i < _size.Length; i++)
                    inh += "[" + i + "]=" + _size[i] + " ";
                inh += "<br>Input_Count = " + Input_Count + "<br>alpha = " + alpha;
                inh += "<br>learningRate = " + learningRate + "<br>Momentum = " + momentum + "<br>LearningLimit = " + learningLimit;
                inh += "<br>S2? " + S2.ToString();
                inh += "<br>learningRate2 = " + learningRate2 + "<br>Momentum2 = " + momentum2 + "<br>LearningLimit2 = " + learningLimit2;
                inh += "<br>_I.Len = " + _I.GetLength(0) + "<br>_I[x].Len = " + _I[0].GetLength(0);
                inh += "<br>_O.Len = " + _O.GetLength(0) + "<br>_O[x].Len = " + _O[0].GetLength(0);
                inh += "<br>Zyklenabbruch = " + zyklenabbruch + "<br>RESTART = " + RESTART + "<br>AF = " + AF.ToString() + "<br>VisualIP = " + Visual_IP + "<br>VisualPort = " + Visual_Port;
                inh += "<br>Mail_aktiv = " + MAIL_Enabled.ToString() + "<br>Mail_From = " + MAIL_FROM + "<br>Mail_To = " + MAIL_TO + "<br>Mail_Port = " + MAIL_Port;
                inh += "<br>Mail_Host = " + MAIL_Host + "<br>Mail_Betreff = " + MAIL_Betreff + "<br>Mail_Auth = " + MAIL_Auth.ToString() + "<br>Mail_USN = " + MAIL_USN;
                inh += "<br>Mail_PW = XXXXXXX";
                IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.DEBUG, inh);
            }

            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "ende");

            return true;
        }

        /// <summary>
        /// Ruft die Konfugration aus der globalen instanz ab
        /// </summary>
        /// <returns></returns>
        public IVisual.I_config GET_CFG()
        {
            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "start");
            IVisual._SC.cls_LOG.WRITE_LOG_LINE(IVisual._SC.cls_LOG.LOGLEVEL.METHOD_INVOKE, "ende");

            return _cls_Config._cfg;
        }
    }
}
